package com.csii.activiti.server.core.listener;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.csii.activiti.server.abstraction.constant.MessageType;
import com.csii.activiti.server.abstraction.entity.ActFlowRemoteCallback;
import com.csii.activiti.server.abstraction.entity.ActReceivedBy;
import com.csii.activiti.server.abstraction.entity.ActSendMessage;
import com.csii.activiti.server.abstraction.service.ActMessageService;
import com.csii.activiti.server.core.constant.ActFlowDataManageConstant;
import com.csii.activiti.server.core.constant.CommonConstant;
import com.csii.activiti.server.core.entity.db.ActFlowPublishConfigEntity;
import com.csii.activiti.server.core.mapper.ActFlowPublishConfigurationMapper;
import com.csii.activiti.server.core.service.FlowCallbackManagementService;
import com.csii.activiti.server.core.service.FlowDataManagementService;
import com.csii.activiti.server.core.utils.ELUtils;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEntityEventImpl;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class FlowEndListener implements ActivitiEventListener, Serializable {
    private static final long serialVersionUID = 1L;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private ActMessageService actMessageService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private FlowDataManagementService flowDataManagementService;

    @Autowired
    private FlowCallbackManagementService flowCallbackManagementService;

    @Autowired
    private ActFlowPublishConfigurationMapper actFlowPublishConfigurationMapper;

    @Autowired
    private RepositoryService repositoryService;


    @Override
    public void onEvent(ActivitiEvent event) {
        if (ActivitiEventType.PROCESS_COMPLETED.equals(event.getType()) && event instanceof ActivitiEntityEventImpl){
            ActivitiEntityEventImpl activitiEntityEvent = (ActivitiEntityEventImpl) event;
            ExecutionEntityImpl entity = (ExecutionEntityImpl) activitiEntityEvent.getEntity();

            ActSendMessage sendMessage = new ActSendMessage();
            sendMessage.setTenantId(entity.getTenantId());
            sendMessage.setProcessName(entity.getName());
            sendMessage.setProcessDefinitionId(entity.getProcessDefinitionId());
            if (entity.getProcessDefinitionId()!= null){
                sendMessage.setProcessKey(entity.getProcessDefinitionId().split(":")[0]);
            }
            sendMessage.setProcessInstanceId(entity.getProcessInstanceId());
            sendMessage.setInitiator(entity.getStartUserId());
            Map<String, Object> formData = (Map<String, Object>) entity.getVariable(CommonConstant.FORM_DATA);
            if (formData == null){
                HistoricVariableInstance formDataVariableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(event.getProcessInstanceId()).variableName(CommonConstant.FORM_DATA).singleResult();
                formData = (Map<String, Object>) formDataVariableInstance.getValue();
            }
            sendMessage.setFormData(formData);
            List<ActFlowRemoteCallback> remoteCallbackList = (List<ActFlowRemoteCallback>) entity.getVariable(CommonConstant.REMOTE_URL);
            if (remoteCallbackList == null){
                HistoricVariableInstance remoteUrlVariableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(event.getProcessInstanceId()).variableName(CommonConstant.REMOTE_URL).singleResult();
                if (remoteUrlVariableInstance != null){
                    remoteCallbackList = (List<ActFlowRemoteCallback>) remoteUrlVariableInstance.getValue();
                }
            }
            if (remoteCallbackList != null){
                sendMessage.setCallbackList(remoteCallbackList);
            }

            sendMessage.setReceivedByList(CollUtil.newArrayList(new ActReceivedBy(null,entity.getStartUserId())));
            //写入数据库
            flowDataManagementService.addData(formData,entity, ActFlowDataManageConstant.PASSED.getStatus());
            //发送消息
            sendMessage.setCurrentDate(new Date());
            String deploymentId = repositoryService.createProcessDefinitionQuery().processDefinitionId(sendMessage.getProcessDefinitionId()).singleResult().getDeploymentId();
            ActFlowPublishConfigEntity flowPublish = actFlowPublishConfigurationMapper.selectOne(new LambdaQueryWrapper<ActFlowPublishConfigEntity>().select(ActFlowPublishConfigEntity::getId, ActFlowPublishConfigEntity::getIconType,ActFlowPublishConfigEntity::getSummary,ActFlowPublishConfigEntity::getManyConditionJson).eq(ActFlowPublishConfigEntity::getId, deploymentId));
            if (flowPublish != null){
                sendMessage.setIconType(flowPublish.getIconType());
                sendMessage.setSummary(ELUtils.getSummary(flowPublish.getSummary(),flowPublish.getManyConditionJson(),formData));
            }
            actMessageService.sendMessage(sendMessage, MessageType.done);
            //触发回调
            flowCallbackManagementService.callback(sendMessage,MessageType.done.getType());

        }
    }


    @Override
    public boolean isFailOnException() {
        return false;
    }
}
